﻿using FlyingEye.Common.Utils;
using FlyingEye.Consts;
using FlyingEye.Users.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;

namespace FlyingEye.Services
{
    public class JwtBearerService : IJwtBearerService
    {
        private readonly IConfiguration _configuration;

        private readonly ApplicationConfiguration _appConfiguration;

        public JwtBearerService(IConfiguration configuration, ApplicationConfiguration applicationConfiguration)
        {
            _configuration = configuration;
            _appConfiguration = applicationConfiguration;
        }

        public string GenerateJwtTokenForever(UserModel user)
        {
            return GenerateJwtToken(user, TimeSpan.MaxValue);
        }

        public string GenerateJwtToken(UserModel user, TimeSpan dueTime)
        {
            var jwtConfig = _configuration.GetSection("Jwt");
            var iss = jwtConfig.GetValue<string>("Issuer");
            var aud = jwtConfig.GetValue<string>("Audience");

            if (string.IsNullOrWhiteSpace(iss))
            {
                throw new InvalidOperationException("Token 的 Issuer 为空！");
            }

            if (string.IsNullOrWhiteSpace(aud))
            {
                throw new InvalidOperationException("Token 的 Audience 为空！");
            }

            DateTime? dateTime;

            if (dueTime.Equals(TimeSpan.MaxValue))
            {
                dateTime = null;
            }
            else
            {
                dateTime = DateTime.Now.Add(dueTime);
            }
            UserRole role = user.Permission;
            var tokenHandler = new JwtSecurityTokenHandler();
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(JwtRegisteredClaimNames.Iss,iss),
                    new Claim(JwtRegisteredClaimNames.Aud,aud),
                    new Claim(ClaimTypes.Role, role.Role),
                    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                }),

                Expires = dateTime,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(_appConfiguration.JwtSecretRowData), SecurityAlgorithms.HmacSha256)
            };

            var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }
}
